package com.kotlin.lib

import kotlin.properties.Delegates
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

fun <T> asList(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts) {
        result.add(t)
    }
    return result
}

fun main() {
    asList(arrayOf(1, 2, 3))
    val user = User()

    user.desc = "setDesc"
    println(user.desc)
    println("**************")

    user.address = "beiJin"

    user.name = "hawking"
    println("--------------${user.address} ${user.name}")

    val user2 = User2(
        mapOf(
            "name" to "john",
            "age" to 13,
            "sex" to "male"
        )
    )
    println(user2)
    val map: MutableMap<String, Any?> = mutableMapOf("name" to "hawk")
    val dynamicUser: User3 = User3(map)
    println("dynamicUsername:${dynamicUser.name}")
    dynamicUser.name = "devZheng"//修改bean，会落实到map里面去
    println("after modify: map value=${map["name"]}, beanValue=${dynamicUser.name}")
    MyImplement().print()
}

class User3 constructor(map: MutableMap<String, Any?>) {
    var name by map
}

interface II {
    fun print()
}

class IIImplement : II {
    override fun print() {
        println("IIImplement")
    }
}

class MyImplement : II by IIImplement() {
    /* override fun print() {//有自己的实现则用自己的实现
         println("MyImplement")
     }*/
}

data class User2(val map: Map<String, Any?>) {
    constructor() : this(mapOf("name" to null, "age" to 0, "sex" to null)) {

    }

    val name: String by map
    val age: Int by map
    val sex: String by map
}

class User {
    var address: String by Delegates.notNull<String>()//get前必须set
    var name: String by Delegates.observable("initialValue") { _, old, new ->
        println("name::property = old = [${old}], new = [${new}]")

    }

    //年龄只能增长，否则不会应用
    var age: Int by Delegates.vetoable(10) { _property, oldValue, newValue ->
        when {
            oldValue < newValue -> true
            else -> false
        }
    }
    var desc: String by DescDelegate()

    val vipCode: String by lazy {
        println("lazy initializer invoked")
        "hello"
    }

}

class DescDelegate : ReadWriteProperty<Any?, String> {
    override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("DescDelegate#setValue ,propertyName:${property.name}, value:$value")
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("DescDelegate#getValue propertyName:${property.name}")
        return "goodBoy"

    }
}